﻿using codeparser.net.v2.Aspects;
using codeparser.net.v2.Contracts;

using System;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;

using Wilco.SyntaxHighlighting;
using codeparser.net.v2.Exceptions;

namespace codeparser.net.v2.SyntaxHighlighter
{
    /// <summary>
    /// Represents the adapter for the syntax highlighting component of Wilco Bauwer.
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
    public class WilcoSyntaxHighlightingAdapter : SyntaxHighlighterBase
    {
        /// <summary>
        /// Gets a list of languages supported by this syntax highlighter.
        /// </summary>
        /// <value>The list of languages.</value>
        public override Collection<Language> SupportedLanguages
        {
            get
            {
                return new Collection<Language>
                {
                    Language.Aspx,
                    Language.C,
                    Language.Cobol,
                    Language.CPlusPlus,
                    Language.CSharp,
                    Language.Css,
                    Language.Eiffel,
                    Language.Fortran,
                    Language.Haskell,
                    Language.Java,
                    Language.JavaScript,
                    Language.JScript,
                    Language.Mercury,
                    Language.Msil,
                    Language.Pascal,
                    Language.Perl,
                    Language.Php,
                    Language.Python,
                    Language.Ruby,
                    Language.Sql,
                    Language.VisualBasic,
                    Language.VisualBasicScript,
                    Language.Xml
                };
            }
        }

        /// <summary>
        /// Initializes a new instance of the WilcoSyntaxHighlightingAdapter type.
        /// </summary>
        /// <param name="language">The language.</param>
        [LoggingAspect]
        public WilcoSyntaxHighlightingAdapter(Language language)
        {
            // Initialize the fields.
            this.Language = language;
        }

        /// <summary>
        /// Highlights the specified text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>The highlighted text.</returns>
        [LoggingAspect]
        public override string Highlight(string text)
        {
            // Get an HTML parser.
            Wilco.SyntaxHighlighting.IParser syntaxHighlightingParser = new HtmlParser();

            // Get the highlighter for the appropriate language.
            Register register = Register.Instance;
            HighlighterBase highlighter = null;
            switch (this.Language)
            {
                case Language.Aspx:
                    highlighter = register.Highlighters["ASPX"];
                    break;
                case Language.C:
                    highlighter = register.Highlighters["C"];
                    break;
                case Language.Cobol:
                    highlighter = register.Highlighters["Cobol"];
                    break;
                case Language.CPlusPlus:
                    highlighter = register.Highlighters["CPP"];
                    break;
                case Language.CSharp:
                    highlighter = register.Highlighters["C#"];
                    break;
                case Language.Css:
                    highlighter = register.Highlighters["CSS"];
                    break;
                case Language.Eiffel:
                    highlighter = register.Highlighters["Eiffel"];
                    break;
                case Language.Fortran:
                    highlighter = register.Highlighters["Fortran"];
                    break;
                case Language.Haskell:
                    highlighter = register.Highlighters["Haskell"];
                    break;
                case Language.Java:
                    highlighter = register.Highlighters["Java"];
                    break;
                case Language.JavaScript:
                    highlighter = register.Highlighters["JavaScript"];
                    break;
                case Language.JScript:
                    highlighter = register.Highlighters["JScript"];
                    break;
                case Language.Mercury:
                    highlighter = register.Highlighters["Mercury"];
                    break;
                case Language.Msil:
                    highlighter = register.Highlighters["MSIL"];
                    break;
                case Language.Pascal:
                    highlighter = register.Highlighters["Pascal"];
                    break;
                case Language.Perl:
                    highlighter = register.Highlighters["Perl"];
                    break;
                case Language.Php:
                    highlighter = register.Highlighters["PHP"];
                    break;
                case Language.Python:
                    highlighter = register.Highlighters["Python"];
                    break;
                case Language.Ruby:
                    highlighter = register.Highlighters["Ruby"];
                    break;
                case Language.Sql:
                    highlighter = register.Highlighters["SQL"];
                    break;
                case Language.VisualBasic:
                    highlighter = register.Highlighters["VisualBasic"];
                    break;
                case Language.VisualBasicScript:
                    highlighter = register.Highlighters["VisualBasicScript"];
                    break;
                case Language.Xml:
                    highlighter = register.Highlighters["XML"];
                    break;
                default:
                    throw new LanguageNotSupportedException("The specified language is not supported by this syntax highlighter");
            }
            highlighter = highlighter.Create();
            highlighter.Parser = syntaxHighlightingParser;
            highlighter.ForceReset();

            // Parse the text.
            return highlighter.Parse(text);
        }
    }
}